/*
 * @Author: LVGRAPE
 * @LastEditors: LVGRAPE
 */
/*
 * @Author: LVGRAPE
 * @LastEditors: LVGRAPE
 */

#pragma once

#ifdef __cplusplus
 extern "C" {
#endif

#include <stdint.h>
typedef uint32_t AT32_MCU_ID;
typedef enum
{
    AT32F403xxx6 = 0x27,  //0X27,
    AT32F413xxx7 = 0x47,  //0X47,
    AT32F415xxx7 = 0x57,  //0X57,
    AT32F403Axxx7 = 0x77, //0X77,
    AT32F407xxx7 = 0x87,  //0X87,
} AT32_MCU_Serial;

typedef enum AT32_MCU_MODEL_LIST
{
    __AT32F403ZCT6 = 0,
    __AT32F403VCT6,
    __AT32F403RCT6,
    __AT32F403CCT6,
    __AT32F403ZGT6,
    __AT32F403VGT6,
    __AT32F403RGT6,
    __AT32F403CGT6,
    __AT32F403ZET6,
    __AT32F403VET6,
    __AT32F403RET6,
    __AT32F403CET6,
    __AT32F403CGU6,
    __AT32F403CEU6,
    __AT32F403CCU6,
    __AT32F413RCT7,
    __AT32F413RBT7,
    __AT32F413CCT7,
    __AT32F413CBT7,
    __AT32F413KCU7_4,
    __AT32F413KBU7_4,
    __AT32F413C8T7,
    __AT32F413CCU7,
    __AT32F413CBU7,
    __AT32F415RCT7,
    __AT32F415CCT7,
    __AT32F415KCU7_4,
    __AT32F415RCT7_7,
    __AT32F415RBT7,
    __AT32F415CBT7,
    __AT32F415KBU7_4,
    __AT32F415RBT7_7,
    __AT32F415R8T7,
    __AT32F415C8T7,
    __AT32F415R8T7_7,
    __AT32F415K8U7_4,
    __AT32F415CBU7,
    __AT32F415CCU7,
    __AT32F403AVCT7,
    __AT32F403ARCT7,
    __AT32F403ACCT7,
    __AT32F403ACCU7,
    __AT32F403AVGT7,
    __AT32F403ARGT7,
    __AT32F403ACGT7,
    __AT32F403ACGU7,
    __AT32F403AVET7,
    __AT32F403ARET7,
    __AT32F403ACET7,
    __AT32F403ACEU7,
    __AT32F407VCT7,
    __AT32F407RCT7,
    __AT32F407VGT7,
    __AT32F407RGT7,
    __AT32F407VET7,
    __AT32F407RET7,
    AT32_MCU_MODEL_COUNT,
} AT32_MCU_MODEL;
typedef enum
{
    _64KB = 0,
    _128KB,
    _256KB,
    _512KB,
    _1024KB,
    AT32_MCU_FLASH_COUNT,
} AT32_MCU_FLASH;
typedef enum
{
    QFN32 = 0,
    QFN48,
    LQFP48,
    LQFP64,
    LQFP100,
    LQFP144,
    AT32_MCU_Footprint_COUNT,
} AT32_MCU_Footprint;
typedef struct mcuInfo
{
    AT32_MCU_Serial Serial:8;
    AT32_MCU_ID ID;
    uint32_t Model:8;
    AT32_MCU_FLASH Flash:8;
    AT32_MCU_Footprint Footprint:8;
    uint8_t UID[12];
} AT32_MCU_TYPE;
typedef enum
{
    Cortex_M0_r0p0 = 0,
    Cortex_M0plus_r0p0,
    Cortex_M1_r0p0,
    Cortex_M1_r0p1,
    Cortex_M1_r1p0,
    Cortex_M3_r0p0,
    Cortex_M3_r1p0,
    Cortex_M3_r1p1,
    Cortex_M3_r2p0,
    Cortex_M3_r2p1,
    Cortex_M4_r0p0,
    Cortex_M4_r0p1,
    Cortex_count,
}AT32_MCU_Cortex;

typedef struct at32_mcu_core_info
{
    AT32_MCU_Cortex core;
    uint32_t id;
}at32_mcu_core;

#define AT32MCU_FOREACH(x) for (uint8_t(x) = 0; (x) < AT32_MCU_MODEL_COUNT; (x)++)

#define MCU_UNIQUE_96BIT_ID_BASE_ADDR_31_0  ((uint32_t)0x1FFFF7E8)
#define MCU_UNIQUE_96BIT_ID_BASE_ADDR_63_32 ((uint32_t)0x1FFFF7EC)
#define MCU_UNIQUE_96BIT_ID_BASE_ADDR_95_64 ((uint32_t)0x1FFFF7F0)
#define AT32_MCU_SERIAL_ADDR 0x1FFFF7F3
#define AT32_MCU_PID_BASE_ADDR 0xE0042000
#define AT32_MCU_SERIAL_ID (*(uint8_t*)AT32_MCU_SERIAL_ADDR)
#define AT32_MCU_PID (*(uint32_t*)AT32_MCU_PID_BASE_ADDR)


extern const char AT32_MCU_Cortex_str[Cortex_count+1][16];
extern const AT32_MCU_TYPE AT32_MCU_LIST[AT32_MCU_MODEL_COUNT];
extern const char AT32_MCU_Model_str[AT32_MCU_MODEL_COUNT + 1][16];
extern const char AT32_MCU_FLASH_str[AT32_MCU_FLASH_COUNT + 1][8];
extern const char AT32_MCU_Footprint_str[AT32_MCU_Footprint_COUNT + 1][8];
extern AT32_MCU_TYPE whoAmI;
// char *at32_mcu_core2str(at32_mcu_core *core);
char *at32_mcu_mode2str(AT32_MCU_TYPE *mcu);
char *at32_mcu_flash2str(AT32_MCU_TYPE *mcu);
char *at32_mcu_footprint2str(AT32_MCU_TYPE *mcu);
char *at32_mcu_core2str(uint32_t id);
uint32_t at32_mcu_get_coreID(void);
uint8_t at32_mcu_who_am_i(AT32_MCU_TYPE *mcu);
uint8_t at32_mcu_init_model(AT32_MCU_TYPE *mcu, char *model);
#ifdef __cplusplus
 }
#endif
